/************************************************************************
 * AIDE/Examples - Automata Identification Engine
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     
 * Description  :     
 * Change log   :     	-Date:  Change
 ************************************************************************/
﻿using System;
using System.Collections.Generic;
using SMLib.Automata.MM;
using SMLib.Automata.Base;

namespace LearningApp.Examples
{
	/// <summary>
	/// Counter class which implements 'IBlackBox_MealyMachine' interface.
	/// It is a black box implementatioin aimed to be learnt
	/// </summary>
	public class Counter : IBlackBox_MM
	{
		class INT_SYMB : ISymbol
		{
			int value;

			public INT_SYMB (int val)
			{
				this.value = val;
			}
			#region ISymbol Members
			public object ContentObject {
				get {
					return value;
				}
				set {
					if (value is int) {
						this.value = (int)value;
					} else
						throw new Exception ("Expecting an integer!");
				}
			}

			public Type TypeOfSymbol ()
			{
				return typeof(INT_SYMB);
			}
			#endregion
			public override string ToString ()
			{
				return value.ToString ();
			}

			public override int GetHashCode ()
			{				
				return base.GetHashCode ();
			}

			public override bool Equals (object obj)
			{
				if (obj is INT_SYMB) {
					return ((INT_SYMB)obj).value == value;
				}
				return false;
			}
		}

		int MAX;
		int count;
		INT_SYMB[] a;
		StringSymbol INC, DEC;

		public Counter (int MAX=5)
		{
			this.MAX = MAX;
			count = 0;
			a = new INT_SYMB[MAX];
			for (int i = 0; i < MAX; i++)
				a [i] = new INT_SYMB (i);

			inp = new Alphabet ();
			INC = new StringSymbol ("INC");
			DEC = new StringSymbol ("DEC");
			inp.AddSymbol (INC);
			inp.AddSymbol (DEC);
		}

		/// <summary>
		/// Creates an instance.
		/// </summary>
		/// <returns>
		/// The instance.
		/// </returns>
		public static IBlackBox_MM CreateInstance ()
		{
			return new Counter ();
		}
		#region IBlackBox_MealyMachine Members
		Alphabet inp;

		public void Reset ()
		{
			count = 0;
		}

		public ISymbol Step (ISymbol input)
		{
			if (input.Equals (INC)) {
				count = (count + 1);
				if (count == MAX) {
					count = 0;
				}
				return a [count];
			} else if (input.Equals (DEC)) {
				count = (count - 1);
				if (count == -1) {
					count = MAX - 1;
				}
				return a [count];
			} else
				throw new Exception ("Wrong input");
		}

		public Alphabet InputAlphabet {
			get { return inp; }
		}
		#endregion
	}
}
